# == Schema Information
#
# Table name: payments
#
#  id             :integer          not null, primary key
#  user_id        :integer
#  payment_no     :string
#  transaction_no :string
#  status         :integer          default(0)
#  total_money    :decimal(10, 2)
#  payment_at     :datetime
#  raw_response   :text
#  created_at     :datetime         not null
#  updated_at     :datetime         not null
#  workflow_state :string
#  order_id       :integer
#  title          :string
#  pay_type       :string
#  charge_id      :string
#  repay_no       :string
#

class Payment < ApplicationRecord

  has_many :payment_histories
  belongs_to :order
  belongs_to :user

  before_create :gen_payment_no

  include Workflow
  include WorkflowPlus
  include Pingppable

  module PayType
    ALIPAY_PC_DIRECT = "alipay_pc_direct"
    ALIPAY_WAP = "alipay_wap"
  end

  workflow do
    state :unpaid do
      event :down_pay, :transitions_to => :down_payment
      event :complete_pay, :transitions_to => :completed
      event :fail, :transitions_to => :failed
    end
    state :down_payment do
      event :tail_pay, :transitions_to => :tail_payment
      event :fail, :transitions_to => :failed
    end

    state :tail_payment
    state :completed
    state :failed
  end

  #生成预支付
  def generate_pay(state="unpaid", remote_ip="127.0.0.1")
    self.pingpp_charge(payment_options(remote_ip))
  end

  def payment_options(remote_ip="127.0.0.1")
    title = Setting.payments[:title]
    {
      order_no: self.repay_no || self.payment_no,
      channel:  self.pay_type,
      subject:  title.byteslice(0, 32),
      body:     self.raw_response.blank? ? title : self.raw_response.byteslice(0,100),
      amount:   self.total_money * 100,
      currency: "cny",
      time_expire: (Time.now + 19.minutes).to_i,
      client_ip: remote_ip
    }.merge(extra_option)
  end

  def extra_option
    domain = Setting.get('domain')
    case self.pay_type
    when "alipay_wap"
      {
        extra: {
          success_url: "http://#{domain}/payments/callback",
          cancel_url: "http://#{domain}/payments/callback",
          app_pay: true
        }
      }
    when "alipay_pc_direct"
      {
        extra: {
          success_url: "http://#{domain}/payments/callback"
        }
      }
    when "wx_wap"
      {
        extra: {
          success_url: "http://#{domain}/payments/callback"
        }
      }
    else
      {
        extra: {}
      }
    end
  end

  class << self

    def create_or_update_payment! user, order, pay_type
      payment = order.payment
      if payment.nil?
        order.build_payment(
          user_id: user.id,
          title: Setting.payments[:title],
          total_money: order.total_money,
          pay_type: pay_type,
          payment_at: Time.now
        )
      else
        history = order.order_histories.find{|x| x.status == 'survey_completed'}
        if history
          payment.repay_no = RandomCode.generate_utoken(32)
          payment.save!
        end
        payment
      end
    end

  end

  private

  def gen_payment_no
    self.payment_no = RandomCode.generate_utoken(32)
  end

end
